package com.example.wxsmart.aspect;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * Spring boot 控制器 请求日志，方便代码调试
 *
 * @author L.cm
 * @date 2022/08/04
 */
@Slf4j
@Aspect
@Component
public class RequestLogAspect {

	/**
	 * AOP 环切 控制器
	 *
	 * @param point JoinPoint
	 * @return Object
	 * @throws Throwable 异常
	 */
	@Around("execution(* com.example.wxsmart.controller.*.*(..))")
	public Object aroundApi(ProceedingJoinPoint point) throws Throwable {
		StringBuilder stringBuilder = new StringBuilder();

		RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
		HttpServletRequest request =  requestAttributes == null ? null : ((ServletRequestAttributes)requestAttributes).getRequest();

		stringBuilder.append("\n================  Request Start  ================");
		stringBuilder.append("\n=== URI  === ").append(request == null ? "null" : request.getRequestURI());
		stringBuilder.append("\n===Method=== ").append(point.getSignature().toString());
		stringBuilder.append("\n===Params=== ").append(Arrays.stream(point.getArgs()).map(Object::toString).collect(Collectors.joining(" || ")));
		long startNs = System.nanoTime();
		Object proceed = point.proceed();
		long endNs = System.nanoTime();
		stringBuilder.append("\n===Result=== ").append(JSON.toJSONString(proceed));
		stringBuilder.append("\n=== Time === ").append(TimeUnit.NANOSECONDS.toMillis(endNs - startNs)).append(" ms");
		stringBuilder.append("\n================   Request End   ================\n");
		log.info(stringBuilder.toString());
		return proceed;
	}

}
